#ifndef QCMDPARSER_H
#define QCMDPARSER_H
#include "cmdline.h"
#include <QString>
#include <functional>

template <> struct cmdline::default_reader<QString> {
  QString operator()(const std::string &str) {
    return QString::fromStdString(str);
  }
};

template <>
inline std::string cmdline::detail::default_value<QString>(QString def) {
  return def.toStdString();
}
class QCmdParser : public cmdline::parser {

public:
  virtual ~QCmdParser();

  QCmdParser &add(const QString &name, char short_name = 0,
                  const QString &desc = "") {
    parser::add(name.toStdString(), short_name, desc.toStdString());
    return *this;
  }

  template <class T>
  QCmdParser &add(const QString &name, char short_name = 0,
                  const QString &desc = "", bool need = true,
                  const T def = T()) {
    parser::add(name.toStdString(), short_name, desc.toStdString(), need, def,
                cmdline::default_reader<T>());
    return *this;
  }

  template <class T, class F>
  QCmdParser &add(const QString &name, char short_name = 0,
                  const QString &desc = "", bool need = true, const T def = T(),
                  F reader = F()) {
    parser::add(name.toStdString(), short_name, desc.toStdString(), need, def,
                reader);
    return *this;
  }

  void addCallBack(std::function<void(QCmdParser *)> cb) { mCallBack = cb; };
  void operator()() { mCallBack(this); }

private:
  static void defaultCB(QCmdParser *){};

  std::function<void(QCmdParser *)> mCallBack = &defaultCB;
};
#endif